from typing import Any, Callable, Dict, TypeVar, Optional
import inspect
import functools
from contextlib import contextmanager, asynccontextmanager

T = TypeVar("T")

class Depends:
    """FastAPI风格依赖包装器"""
    def __init__(self, dependency: Callable[..., T] = None, *, use_cache: bool = True):
        self.dependency = dependency
        self.use_cache = use_cache

    def __call__(self) -> T:
        return self.dependency() if self.dependency else None
    

class DependencyResolver:
    def __init__(self):
        self.overrides: Dict[Callable, Callable] = {}
        self.cache: Dict[str, Any] = {}

    async def resolve(
        self,
        dependency: Callable,
        *,
        skip_cache: bool = False,
        **extra_params
    ) -> Any:
        """递归解析依赖树"""
        # 检查依赖覆盖
        actual_dep = self.overrides.get(dependency, dependency)
        
        # 缓存检查
        cache_key = f"{actual_dep.__module__}.{actual_dep.__name__}"
        if not skip_cache and self.cache.get(cache_key):
            return self.cache[cache_key]

        # 获取函数签名
        sig = inspect.signature(actual_dep)
        
        # 构建参数
        kwargs = {}
        for name, param in sig.parameters.items():
            if isinstance(param.default, Depends):
                # 递归解析子依赖
                resolved = await self.resolve(param.default.dependency)
                kwargs[name] = resolved
            elif name in extra_params:
                kwargs[name] = extra_params[name]

        # 执行依赖
        if inspect.iscoroutinefunction(actual_dep):
            result = await actual_dep(**kwargs)
        else:
            result = actual_dep(**kwargs)

        # 缓存结果
        if not skip_cache:
            self.cache[cache_key] = result

        return result
    

class DependencyContainer:
    def __init__(self):
        self.resolver = DependencyResolver()
        self.request_scoped_cache = {}

    @contextmanager
    def request_context(self):
        """请求级上下文管理器"""
        try:
            self.request_scoped_cache.clear()
            yield
        finally:
            # 清理请求级资源
            for dep in self.request_scoped_cache.values():
                if hasattr(dep, '__exit__'):
                    dep.__exit__(None, None, None)

    def override(self, dependency: Callable, override_with: Callable) -> None:
        """测试依赖覆盖"""
        self.resolver.overrides[dependency] = override_with

    def reset_overrides(self) -> None:
        """重置所有覆盖"""
        self.resolver.overrides.clear()

# --------------------------------------------------------------------------
# # 类依赖支持
# class AuthService:
#     def __init__(self, db: str = Depends(get_db)):
#         self.db = db

# # 参数化依赖
# def get_config(env: str):
#     def inner_config():
#         return {"env": env, "key": "secret"}
#     return Depends(inner_config)

# # 作用域控制
# class Scope:
#     APPLICATION = 1
#     REQUEST = 2

# --------------------------------------------------------------------------

print("-----------1---------------------")
# 定义依赖项
async def get_db():
    print("Connecting to DB...")
    yield "DB Connection"
    print("Closing DB connection...")

def get_current_user(db: str = Depends(get_db)):
    return {"user": "admin", "db": db}

print("-----------2---------------------")
# 初始化容器
container = DependencyContainer()

print("----------3----------------------")
# 使用示例
async def main():
    with container.request_context():
        print("------------解析依赖--------------------")
        # 解析依赖
        user = await container.resolver.resolve(get_current_user)
        print(user)  # 输出: {'user': 'admin', 'db': 'DB Connection'}

        # 测试覆盖
        container.override(get_db, lambda: "Mock DB")
        mock_user = await container.resolver.resolve(get_current_user)
        print(mock_user)  # 输出: {'user': 'admin', 'db': 'Mock DB'}

print("--------------------------------")
# 运行
import asyncio
asyncio.run(main())        

"""  一个对象的依赖关系不是由该对象自己创建或管理的，而是由外部容器或框架来提供和管理
1.  注入依赖
2.  构建上下文管理器
3.  递归解析依赖树，并执行依赖，缓存结果， 返回结果


"""